#include "unione_lite.h"
#include "ftpwmtimer.h"
#include "DrvUART010.h"

ftpwmtmr_t *gpwmReg =(ftpwmtmr_t *) PWM_FTPWMTMR010_PA_BASE;
#if 0
static void fLib_pwm_reg_print(u8 pwm_num)
{
  switch(pwm_num){
    case 1:
      fLib_printf("timer1_cr(0x%x) = 0x%x\n", &(gpwmReg->timer1_cr), gpwmReg->timer1_cr);
      fLib_printf("timer1_counter(0x%x) = 0x%x\n", &(gpwmReg->timer1_cntb), gpwmReg->timer1_cntb);
      fLib_printf("timer1_compare(0x%x) = 0x%x\n", &(gpwmReg->timer1_cmpb), gpwmReg->timer1_cmpb);
      fLib_printf("timer1_cnto(0x%x) = 0x%x\n", &(gpwmReg->timer1_cnto), gpwmReg->timer1_cnto);
      break;
    case 2:
      fLib_printf("timer2_cr(0x%x) = 0x%x\n", &(gpwmReg->timer2_cr), gpwmReg->timer2_cr);
      fLib_printf("timer2_counter(0x%x) = 0x%x\n", &(gpwmReg->timer2_cntb), gpwmReg->timer2_cntb);
      fLib_printf("timer2_compare(0x%x) = 0x%x\n", &(gpwmReg->timer2_cmpb), gpwmReg->timer2_cmpb);
      fLib_printf("timer2_cnto(0x%x) = 0x%x\n", &(gpwmReg->timer2_cnto), gpwmReg->timer2_cnto);
      break;
    case 3:
      fLib_printf("timer3_cr(0x%x) = 0x%x\n", &(gpwmReg->timer3_cr), gpwmReg->timer3_cr);
      fLib_printf("timer3_counter(0x%x) = 0x%x\n", &(gpwmReg->timer3_cntb), gpwmReg->timer3_cntb);
      fLib_printf("timer3_compare(0x%x) = 0x%x\n", &(gpwmReg->timer3_cmpb), gpwmReg->timer3_cmpb);
      fLib_printf("timer3_cnto(0x%x) = 0x%x\n", &(gpwmReg->timer3_cnto), gpwmReg->timer3_cnto);
      break;
    case 4:
      fLib_printf("timer4_cr(0x%x) = 0x%x\n", &(gpwmReg->timer4_cr), gpwmReg->timer4_cr);
      fLib_printf("timer4_counter(0x%x) = 0x%x\n", &(gpwmReg->timer4_cntb), gpwmReg->timer4_cntb);
      fLib_printf("timer4_compare(0x%x) = 0x%x\n", &(gpwmReg->timer4_cmpb), gpwmReg->timer4_cmpb);
      fLib_printf("timer4_cnto(0x%x) = 0x%x\n", &(gpwmReg->timer4_cnto), gpwmReg->timer4_cnto);
      break;
    case 5:
      fLib_printf("timer5_cr(0x%x) = 0x%x\n", &(gpwmReg->timer5_cr), gpwmReg->timer5_cr);
      fLib_printf("timer5_counter(0x%x) = 0x%x\n", &(gpwmReg->timer5_cntb), gpwmReg->timer5_cntb);
      fLib_printf("timer5_compare(0x%x) = 0x%x\n", &(gpwmReg->timer5_cmpb), gpwmReg->timer5_cmpb);
      fLib_printf("timer5_cnto(0x%x) = 0x%x\n", &(gpwmReg->timer5_cnto), gpwmReg->timer5_cnto);
      break;
    case 6:
      fLib_printf("timer6_cr(0x%x) = 0x%x\n", &(gpwmReg->timer6_cr), gpwmReg->timer6_cr);
      fLib_printf("timer6_counter(0x%x) = 0x%x\n", &(gpwmReg->timer6_cntb), gpwmReg->timer6_cntb);
      fLib_printf("timer6_compare(0x%x) = 0x%x\n", &(gpwmReg->timer6_cmpb), gpwmReg->timer6_cmpb);
      fLib_printf("timer6_cnto(0x%x) = 0x%x\n", &(gpwmReg->timer6_cnto), gpwmReg->timer6_cnto);
      break;
    case 7:
      fLib_printf("timer7_cr(0x%x) = 0x%x\n", &(gpwmReg->timer7_cr), gpwmReg->timer7_cr);
      fLib_printf("timer7_counter(0x%x) = 0x%x\n", &(gpwmReg->timer7_cntb), gpwmReg->timer7_cntb);
      fLib_printf("timer7_compare(0x%x) = 0x%x\n", &(gpwmReg->timer7_cmpb), gpwmReg->timer7_cmpb);
      fLib_printf("timer7_cnto(0x%x) = 0x%x\n", &(gpwmReg->timer7_cnto), gpwmReg->timer7_cnto);
      break;
    case 8:
      fLib_printf("timer8_cr(0x%x) = 0x%x\n", &(gpwmReg->timer8_cr), gpwmReg->timer8_cr);
      fLib_printf("timer8_counter(0x%x) = 0x%x\n", &(gpwmReg->timer8_cntb), gpwmReg->timer8_cntb);
      fLib_printf("timer8_compare(0x%x) = 0x%x\n", &(gpwmReg->timer8_cmpb), gpwmReg->timer8_cmpb);
      fLib_printf("timer8_cnto(0x%x) = 0x%x\n", &(gpwmReg->timer8_cnto), gpwmReg->timer8_cnto);
      break;
    default:
      fLib_printf("fLib_pwm_reg_print failed! invalid pwm_num = %d\n", pwm_num);
      break;
  }
}
#endif
static void fLib_config_pwm(u8 pwm_num, u32 counter,u32 cmp_value)
{
  switch(pwm_num){
    case 1:
      gpwmReg->timer1_cntb = counter;
      gpwmReg->timer1_cmpb = cmp_value;
      break;
    case 2:
      gpwmReg->timer2_cntb = counter;
      gpwmReg->timer2_cmpb = cmp_value;
      break;
    case 3:
      gpwmReg->timer3_cntb = counter;
      gpwmReg->timer3_cmpb = cmp_value;
      break;
    case 4:
      gpwmReg->timer4_cntb = counter;
      gpwmReg->timer4_cmpb = cmp_value;
      break;
    case 5:
      gpwmReg->timer5_cntb = counter;
      gpwmReg->timer5_cmpb = cmp_value;
      break;
    case 6:
      gpwmReg->timer6_cntb = counter;
      gpwmReg->timer6_cmpb = cmp_value;
      break;
    case 7:
      gpwmReg->timer7_cntb = counter;
      gpwmReg->timer7_cmpb = cmp_value;
      break;
    case 8:
      gpwmReg->timer8_cntb = counter;
      gpwmReg->timer8_cmpb = cmp_value;
      break;
    default:
      fLib_printf("fLib_config_pwm failed! invalid pwm_num = %d\n", pwm_num);
      break;
  }
}

static void fLib_start_pwm(u8 pwm_num)
{
  switch(pwm_num)
  {
    case 1:
      gpwmReg->timer1_cr = FTPWMTMR_PWMEN | FTPWMTMR_AUTOLOAD | FTPWMTMR_UPDATE | FTPWMTMR_START;
      break;
    case 2:
      gpwmReg->timer2_cr = FTPWMTMR_PWMEN | FTPWMTMR_AUTOLOAD | FTPWMTMR_UPDATE | FTPWMTMR_START;
      break;
    case 3:
      gpwmReg->timer3_cr = FTPWMTMR_PWMEN | FTPWMTMR_AUTOLOAD | FTPWMTMR_UPDATE | FTPWMTMR_START;
      break;
    case 4:
      gpwmReg->timer4_cr = FTPWMTMR_PWMEN | FTPWMTMR_AUTOLOAD | FTPWMTMR_UPDATE | FTPWMTMR_START;
      break;
    case 5:
      gpwmReg->timer5_cr = FTPWMTMR_PWMEN | FTPWMTMR_AUTOLOAD | FTPWMTMR_UPDATE | FTPWMTMR_START;
      break;
    case 6:
      gpwmReg->timer6_cr = FTPWMTMR_PWMEN | FTPWMTMR_AUTOLOAD | FTPWMTMR_UPDATE | FTPWMTMR_START;
      break;
    case 7:
      gpwmReg->timer7_cr = FTPWMTMR_PWMEN | FTPWMTMR_AUTOLOAD | FTPWMTMR_UPDATE | FTPWMTMR_START;
      break;
    case 8:
      gpwmReg->timer8_cr = FTPWMTMR_PWMEN | FTPWMTMR_AUTOLOAD | FTPWMTMR_UPDATE | FTPWMTMR_START;
      break;
    default:
      fLib_printf("fLib_start_pwm failed! invalid pwm_num = %d\n", pwm_num);
      break;
  }
}

static void fLib_stop_pwm(u8 pwm_num)
{    
  switch(pwm_num){
    case 1:
      gpwmReg->timer1_cr = 0;
      break;
    case 2:
      gpwmReg->timer2_cr = 0;
      break;
    case 3:
      gpwmReg->timer3_cr = 0;
      break;
    case 4:
      gpwmReg->timer4_cr = 0;
      break;
    case 5:
      gpwmReg->timer5_cr = 0;
      break;
    case 6:
      gpwmReg->timer6_cr = 0;
      break;
    case 7:
      gpwmReg->timer7_cr = 0;
      break;
    case 8:
      gpwmReg->timer8_cr = 0;
      break;
    default:
      fLib_printf("fLib_stop_pwm failed! invalid pwm_num = %d\n", pwm_num);
      break;
  }
}

/*
pwm_num: timer num from 1~8
freq_hz: frequency of output waveform, must be < pclk = 45.056M
duty_cycle: should be within 100, i.e. if 50% duty cycle wanted, then duty_cycle = 50
*/
void fLib_pwm_enable(u8 pwm_num, u32 freq_hz, u32 duty_cycle)
{
  u32 pclk = 45056000;//current pclk = 45.056M
  u32 counter = pclk/freq_hz;
  u32 cmp_value = (counter * duty_cycle) / 100;

  if (pwm_num == 0 || pwm_num > 8) {
    fLib_printf("fLib_pwm_enable failed! invalid pwm_num = %d\n", pwm_num);
    return;
  }
  //set pwm pinmux by UniPinmuxTool

  fLib_stop_pwm(pwm_num);
  fLib_config_pwm(pwm_num, counter, cmp_value);
  fLib_start_pwm(pwm_num);
  //fLib_pwm_reg_print(pwm_num); //for debug
  return;
}

void fLib_pwm_disable(u8 pwm_num)
{
  fLib_stop_pwm(pwm_num);
  return;
}

